home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / qix / qmove.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-01-28  |  6.5 KB  |  242 lines

  1. #include "qix.h"
  2. /*
  3.  * Code to draw and move the qix.
  4.  */
  5.  
  6. #define QSIZE     45    /* Max size for lines in the Qix */
  7. #define DTHRESH     ((4+level)/3)    /* larger ==> more active */
  8. #define FUDGE     (Speed)
  9. #define NLINES     8    /* Max. # lines in the Qix itself */
  10.  
  11. /* Qix position: */
  12. int
  13.     qix1_x0[NLINES], qix1_x1[NLINES], qix1_y0[NLINES], qix1_y1[NLINES],
  14.     qix1_dx0, qix1_dx1, qix1_dy0, qix1_dy1,    /* velocity */
  15.     qix2_x0[NLINES], qix2_x1[NLINES], qix2_y0[NLINES], qix2_y1[NLINES],
  16.     qix2_dx0, qix2_dx1, qix2_dy0, qix2_dy1;    /* velocity */
  17.  
  18. init_qix()
  19. {
  20.     int x;
  21.     Speed = 3;
  22.  
  23.     for (x = 0; x < NLINES; x++) {
  24.     qix1_x0[x] = BOARD_WIDTH / 2 + (rrand() & 3) - 6;
  25.     qix1_x1[x] = qix1_x0[x] + 2;
  26.     qix1_y0[x] = (BOARD_HEIGHT-10) / 2 + (rrand() & 3) - 6;
  27.     qix1_y1[x] = qix1_y0[x] + 2;
  28.  
  29.     qix2_x0[x] = BOARD_WIDTH / 2 + (rrand() & 3) - 6;
  30.     qix2_x1[x] = qix2_x0[x] + 2;
  31.     qix2_y0[x] = (BOARD_HEIGHT-10) / 2 + (rrand() & 3) - 6;
  32.     qix2_y1[x] = qix2_y0[x] + 2;
  33.     }
  34. }
  35.  
  36. move_qix()
  37. {
  38.     static index = 0, count;
  39.     int i, j;
  40.  
  41.     if (level < 0 && count++ & 1)
  42.     return 0;
  43.  
  44.     if (qix1_x0[index] <= 0)
  45.     qix1_x0[index] = 1;
  46.     if (qix1_x0[index] >= BOARD_WIDTH-1)
  47.     qix1_x0[index] = BOARD_WIDTH-2;
  48.     if (qix1_x1[index] <= 0)
  49.     qix1_x1[index] = 1;
  50.     if (qix1_x1[index] >= BOARD_WIDTH-1)
  51.     qix1_x1[index] = BOARD_WIDTH-2;
  52.     if (qix1_y0[index] <= 0)
  53.     qix1_y0[index] = 1;
  54.     if (qix1_y0[index] >= BOARD_HEIGHT-1)
  55.     qix1_y0[index] = BOARD_HEIGHT-2;
  56.     if (qix1_y1[index] <= 0)
  57.     qix1_y1[index] = 1;
  58.     if (qix1_y1[index] >= BOARD_HEIGHT-1)
  59.     qix1_y1[index] = BOARD_HEIGHT-2;
  60.  
  61.     if (level > -1) {
  62.     if (qix2_x0[index] <= 0)
  63.         qix2_x0[index] = 1;
  64.     if (qix2_x0[index] >= BOARD_WIDTH-1)
  65.         qix2_x0[index] = BOARD_WIDTH-2;
  66.     if (qix2_x1[index] <= 0)
  67.         qix2_x1[index] = 1;
  68.     if (qix2_x1[index] >= BOARD_WIDTH-1)
  69.         qix2_x1[index] = BOARD_WIDTH-2;
  70.     if (qix2_y0[index] <= 0)
  71.         qix2_y0[index] = 1;
  72.     if (qix2_y0[index] >= BOARD_HEIGHT-1)
  73.         qix2_y0[index] = BOARD_HEIGHT-2;
  74.     if (qix2_y1[index] <= 0)
  75.         qix2_y1[index] = 1;
  76.     if (qix2_y1[index] >= BOARD_HEIGHT-1)
  77.         qix2_y1[index] = BOARD_HEIGHT-2;
  78.     }
  79.  
  80.     j = bounds(qix1_x0[index], qix1_y0[index],
  81.            qix1_x1[index], qix1_y1[index],
  82.            &qix1_dx0, &qix1_dy0, &qix1_dx1, &qix1_dy1);
  83.     if (j != -1 && level > -1)
  84.     j = bounds(qix2_x0[index],qix2_y0[index],qix2_x1[index],qix2_y1[index],
  85.         &qix2_dx0, &qix2_dy0, &qix2_dx1, &qix2_dy1);
  86.  
  87.     i = (index + 1) % NLINES;
  88.  
  89.     /* erase old line */
  90.     draw(convert_x(qix1_x0[i]), convert_y(qix1_y0[i]),
  91.      convert_x(qix1_x1[i]), convert_y(qix1_y1[i]), PIX_CLR);
  92.     if (level > -1)
  93.     draw(convert_x(qix2_x0[i]), convert_y(qix2_y0[i]),
  94.          convert_x(qix2_x1[i]), convert_y(qix2_y1[i]), PIX_CLR);
  95.  
  96.     qix1_x0[i] = qix1_x0[index] + qix1_dx0;
  97.     qix1_y0[i] = qix1_y0[index] + qix1_dy0;
  98.     qix1_x1[i] = qix1_x1[index] + qix1_dx1;
  99.     qix1_y1[i] = qix1_y1[index] + qix1_dy1;
  100.  
  101.     if (level > -1) {
  102.     qix2_x0[i] = qix2_x0[index] + qix2_dx0;
  103.     qix2_y0[i] = qix2_y0[index] + qix2_dy0;
  104.     qix2_x1[i] = qix2_x1[index] + qix2_dx1;
  105.     qix2_y1[i] = qix2_y1[index] + qix2_dy1;
  106.     }
  107.     index = i;
  108.  
  109.     draw(convert_x(qix1_x0[i]), convert_y(qix1_y0[i]),
  110.      convert_x(qix1_x1[i]), convert_y(qix1_y1[i]), PIX_SRC);
  111.     if (level > -1)
  112.     draw(convert_x(qix2_x0[i]), convert_y(qix2_y0[i]),
  113.          convert_x(qix2_x1[i]), convert_y(qix2_y1[i]), PIX_SRC);
  114.     return j;
  115. }
  116.  
  117. bounds(x0, y0, x1, y1, dx0, dy0, dx1, dy1)
  118. register int x0, y0, x1, y1;
  119. register int *dx0, *dy0, *dx1, *dy1;
  120. {
  121.     register int i, new_x0, new_y0, new_x1, new_y1;
  122.     int count, loop_count = 0;
  123.  
  124.     /* randomly change direction */
  125.     if (!(rrand() % 10)) {
  126.     register int r;
  127.     /* move at least one space, but not greater than "Speed" */
  128.     *dx0 = (1 + (r = rrand())%(Speed-1)) * ((r&1) ? -1 : 1);
  129.     *dy0 = (1 + (r = rrand())%(Speed-1)) * ((r&1) ? -1 : 1);
  130.     *dx1 = (1 + (r = rrand())%(Speed-1)) * ((r&1) ? -1 : 1);
  131.     *dy1 = (1 + (r = rrand())%(Speed-1)) * ((r&1) ? -1 : 1);
  132.     /* check that qix is moving towards player */
  133.     if (level > -2 && !(rrand() % (6 - level))) {
  134.         if (pen_x - x0 > 0 && *dx0 < 0)
  135.         *dx0 = -*dx0;
  136.         if (pen_x - x1 > 0 && *dx1 < 0)
  137.         *dx1 = -*dx1;
  138.         if (pen_y - y0 > 0 && *dy0 < 0)
  139.         *dy0 = -*dy0;
  140.         if (pen_y - y1 > 0 && *dy1 < 0)
  141.         *dy1 = -*dy1;
  142.     }
  143.     }
  144.  
  145.     do  {
  146.     if (x0 + *dx0 <= 1 || x0 + *dx0 >= BOARD_WIDTH-2)
  147.         *dx0 = -*dx0;
  148.     if (x1 + *dx1 <= 1 || x1 + *dx1 >= BOARD_WIDTH-2)
  149.         *dx1 = -*dx1;
  150.     if (y0 + *dy0 <= 1 || y0 + *dy0 >= BOARD_HEIGHT-2)
  151.         *dy0 = -*dy0;
  152.     if (y1 + *dy1 <= 1 || y1 + *dy1 >= BOARD_HEIGHT-2)
  153.         *dy1 = -*dy1;
  154.  
  155.     new_x0 = x0 + *dx0;
  156.     new_x1 = x1 + *dx1;
  157.     new_y0 = y0 + *dy0;
  158.     new_y1 = y1 + *dy1;
  159.  
  160.     /* Prevent Qix from growing too large: */
  161.     if ((abs(new_x1 - new_x0) > QSIZE) || (abs((*dx0)-(*dx1)) < DTHRESH))
  162.         if (rrand()&1)
  163.         *dx1 += (x1<x0 ? FUDGE : -FUDGE), new_x1 = x1 + *dx1;
  164.         else
  165.         *dx0 += (x0<x1 ? FUDGE : -FUDGE), new_x0 = x0 + *dx0;
  166.     if ((abs(new_y1 - new_y0) > QSIZE) || (abs((*dy0)-(*dy1)) < DTHRESH)) 
  167.         if (rrand()&1)
  168.         (*dy1) += (y1<y0 ? FUDGE : -FUDGE), new_y1 = y1 + *dy1;
  169.         else
  170.         (*dy0) += (y0<y1 ? FUDGE : -FUDGE), new_y0 = y0 + *dy0;
  171.  
  172.     /* if we hit a wall, try again */
  173.     if ((count = check_line(new_x0, new_y0, new_x1, new_y1)) == 1) {
  174.         register int r;
  175.         *dx0 = (1 + (r = rrand())%Speed) * ((r&1) ? -1 : 1);
  176.         *dy0 = (1 + (r = rrand())%Speed) * ((r&1) ? -1 : 1);
  177.         *dx1 = (1 + (r = rrand())%Speed) * ((r&1) ? -1 : 1);
  178.         *dy1 = (1 + (r = rrand())%Speed) * ((r&1) ? -1 : 1);
  179.     }
  180.     if (!(++loop_count % 100)) {
  181. #ifdef DEBUG
  182.         msg("bad news... loop count hit %d", loop_count);
  183.         sleep(2);
  184.         remove_msgs(0);
  185. #endif DEBUG
  186.         break;
  187.     }
  188.     } while(count == 1);
  189.     return count;
  190. }
  191.  
  192. check_line(x1, y1, x2, y2)
  193. {
  194.     register double dx_step, dy_step, x, y;
  195.     int dx, dy, steps;
  196.  
  197.     x = x1 + 0.5, y = y1 + 0.5;
  198.     dx = x2 - x1;
  199.     dy = y2 - y1;
  200.  
  201.     steps = max(abs(dx), abs(dy)) + 1;
  202.     dx_step = (double)((double)dx / (double)steps);
  203.     dy_step = (double)((double)dy / (double)steps);
  204.  
  205.     while (steps--) {
  206.     if (board[(int)x][(int)y]) {
  207.         if (
  208. #ifdef DEBUG
  209.         !no_qix_kill &&
  210. #endif DEBUG
  211.         (board[(int)x][(int)y] & NEW_LINE))
  212.         return -1;
  213.         return 1;  /* just an intersect, return */
  214.     }
  215.     x += dx_step;
  216.     y += dy_step;
  217.     }
  218.     return 0;
  219. }
  220.  
  221. get_qix_pos(which, x, y)
  222. register int *x, *y;
  223. {
  224.     register int i;
  225.     int *x0, *y0, *x1, *y1;
  226.  
  227.     if (which == 0)
  228.     x0 = qix1_x0, y0 = qix1_y0, x1 = qix1_x1, y1 = qix1_y1;
  229.     else
  230.     x0 = qix2_x0, y0 = qix2_y0, x1 = qix2_x1, y1 = qix2_y1;
  231.  
  232.     for (i = 0; i < NLINES; i++)
  233.     if (!board[x0[i]][y0[i]]) {
  234.         *x = x0[i], *y = y0[i];
  235.         return 0;
  236.     }
  237.     msg("The qix is trapped in a place it shouldn't have gotten to!");
  238.     sleep(2);
  239.     remove_msgs(0);
  240.     return -1;
  241. }
  242.